//---------------------------------------------------------------------------------
// Copyright (c) 2008 VoiceLynx Project
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
//     1. The origin of this software must not be misrepresented; you must not
//        claim that you wrote the original software. If you use this software
//        in a product, an acknowledgment in the product documentation would be
//        appreciated but is not required.
//
//     2. Altered source versions must be plainly marked as such, and must not be
//        misrepresented as being the original software.
//
//     3. This notice may not be removed or altered from any source
//        distribution.
//---------------------------------------------------------------------------------

#include "VLCore.h"

#include "VLClientApp.h"

VLBaseCore::VLBaseCore(VLPacketLogicPtr packetLogic)
: mPacketLogic(packetLogic.release()),
  mPacketTranslator(*mPacketLogic)
{
  mPacketLogic->setPacketTranslator(mPacketTranslator);
  mPacketLogic->configurePacketTypes(true);
}

VLBaseCore::~VLBaseCore()
{
  mPacketLogic->configurePacketTypes(false);
}

VLRawOutgoingPacketPtr VLBaseCore::takeOutgoingData()
{
  return mPacketTranslator.takeOutgoingData();
}

void VLBaseCore::giveIncomingData(VLRawIncomingPacketPtr data)
{
  mPacketTranslator.giveIncomingData(data);
}

VLDisconnectRequestPtr VLBaseCore::takeDisconnectRequest()
{
  return mPacketTranslator.takeDisconnectRequest();
}

void VLBaseCore::onConnect(VLHostId hostId)
{
  mPacketTranslator.onConnect(hostId);
}

void VLBaseCore::onDisconnect(VLHostId hostId)
{
  mPacketTranslator.onDisconnect(hostId);
}

VLPacketLogic & VLBaseCore::getPacketLogic()
{
  return *mPacketLogic.get();
}

VLClientCore::VLClientCore(VLPacketLogicPtr packetLogic)
: VLBaseCore(packetLogic),
  mCodec(new VLSpeexCodec()),
  mController(0),
  mIsTransmitting(false)
{
  mSoundManager.reset(new VLFModSoundManager());

  mEncoder = mCodec->createEncoder();
  mDecoder = mCodec->createDecoder();

  mStartTalkingSound = mSoundManager->createStaticSound("media/starttalk.wav");
  mStopTalkingSound = mSoundManager->createStaticSound("media/stoptalk.wav");
}

VLIController *VLClientCore::getController()
{
  return mController;
}

void VLClientCore::setController(VLIController *controller)
{
  mController = controller;
}

float VLClientCore::getTxVolume()
{
  return mSoundManager->getTxVolume();
}

void VLClientCore::think()
{
  bool shouldTransmit = false;

  if (mController)
  {
    shouldTransmit = mController->shouldOpenVoice() && (mController->shouldCloseVoice() == false);
  }

  if (shouldTransmit != mIsTransmitting)
  {
    //mSoundManager.setCaptureEnabled(shouldTransmit);
    mIsTransmitting = shouldTransmit;

    if (shouldTransmit == true)
    {
      mSoundManager->clearCapturedSoundData();
      mPacketLogic->onStartVoice();
      mStartTalkingSound->play();
    }
    else
    {
      mPacketLogic->onStopVoice();
      mStopTalkingSound->play();
    }
  }

  // We constantly flush out the recording buffer - we may or may not send via network
  VLByteArrayPtr soundData = mSoundManager->takeCapturedSoundData();

  if (mIsTransmitting)
  {
    VLByteArrayPtr encodedData = mEncoder->encode(soundData);

    if (encodedData.get() != 0)
    {
      mPacketLogic->onVoiceData(encodedData);
    }
  }

  mPacketLogic->process();
  mSoundManager->process();
}

VLServerCore::VLServerCore(VLPacketLogicPtr packetLogic)
: VLBaseCore(packetLogic)
{
  
}

void VLServerCore::think()
{
  mPacketLogic->process();
}
